package org.vectrics.company;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.vectrics.DataException;
import org.vectrics.SystemException;
import org.vectrics.common.db.Criteria;
import org.vectrics.common.util.StringUtils;
import org.vectrics.domain.Domain;
import org.vectrics.employee.Employee;
import org.vectrics.employee.JobTermReference;
import org.vectrics.event.Event;
import org.vectrics.event.EventType;
import org.vectrics.hibernate.Filter;
import org.vectrics.hibernate.Selector;
import org.vectrics.hibernate.ThreadProperties;
import org.vectrics.provider.CoreServiceLocator;
import org.vectrics.recruiter.RecruitServiceLocator;
import org.vectrics.recruiter.company.RecruitCompanyService;
import org.vectrics.recruiter.job.JobTerm;
import org.vectrics.user.Person;

public class CompanyPersistMgr implements CompanyService {
    private transient static Logger log = Logger.getLogger(CompanyPersistMgr.class);

    public CompanyPersistMgr() {
    }

    public Company findCompanyWithName(String companyName) {
        Company company = null;

        Filter filter = new Filter();
        filter.addFrom("Company", "company");
        filter.addSelectField("company");
        filter.addParameterCondition("company.name", "=", companyName);
        Iterator iter = filter.createQuery(ThreadProperties.getSession()).iterate();
        if (iter.hasNext())
            company = (Company) iter.next();

        return (company);
    }

    public Set findCompanyPersonsForPerson(Person person) {
        Set companies = new HashSet();
        Filter filter = new Filter();
        filter.addSelectField("distinct(companyPerson)");
        filter.addFrom("org.vectrics.company.CompanyPerson", "companyPerson");
        filter.addParameterCondition("companyPerson.person.id", "=", person.getId());
        filter.addCondition("companyPerson.voided='F'");
        Session session = ThreadProperties.getSession();
        Query query = filter.createQuery(session);
        companies.addAll(query.list());
        return (companies);
    }

    public Set findCompaniesForPerson(Person person) {
        Set companies = new HashSet();
        Filter filter = new Filter();
        filter.addSelectField("distinct(companyPerson.company)");
        filter.addFrom("org.vectrics.company.CompanyPerson", "companyPerson");
        filter.addParameterCondition("companyPerson.person.id", "=", person.getId());
        filter.addCondition("companyPerson.voided='F'");
        Session session = ThreadProperties.getSession();
        Query query = filter.createQuery(session);
        companies.addAll(query.list());
        return (companies);
    }

    public Sector findSector(String code) {
        Sector sector = (Sector) ThreadProperties.getSession().load(Sector.class, code);
        return (sector);
    }

    public Collection findAllSectors() {
        Filter filter = new Filter();
        filter.addSelectField("sector");
        filter.addFrom("Sector", "sector");
        filter.addOrderBy("sector.descriptionCode");
        Collection sectors = filter.createQuery(ThreadProperties.getSession()).list();
        return (sectors);
    }

    public Company createCompany(Domain domain, String companyName, Company parent, Sector sector) {
        log.debug("createCompany() called");
        Company company = new Company();
        company.setName(companyName);
        company.setReferenceId(this.getNextReferenceId());
        company.setSector(sector);
        company.setParent(parent);
        company.setDomain(domain);
        company.setDateLastChange(new Date());
        this.updateCompany(company);
        return (company);
    }

    public Company createCompanyAndDomain(String companyName, Company parent, Domain parentDomain, Sector sector) {
        Domain newDomain = null;
        if (CoreServiceLocator.getConfiguration().getSingleDomain(parentDomain)) {
            throw new SystemException("Cannot create new data owner for new company, parent data"
                    + " owner has setting that only allows a single data owner, Parent data owner: "
                    + parentDomain.getDescription());
        }
        boolean domainCreated = false;
        if (newDomain == null) {
            domainCreated = true;
            newDomain = new Domain();
            newDomain.setPrimaryCompany(CoreServiceLocator.getSystemService().findSystemDomain().getPrimaryCompany());
            newDomain.setParent(parentDomain);

            newDomain.setDescription(companyName);
            if (parent == null)
                newDomain.setParent(CoreServiceLocator.getSystemService().findSystemDomain());
            else
                newDomain.setParent(parent.getDomain());
        }
        CoreServiceLocator.getSystemService().updateDomain(newDomain);
        Company company = createCompany(newDomain, companyName, parent, sector);

        if (domainCreated) {
            newDomain.setPrimaryCompany(company);
            CoreServiceLocator.getSystemService().updateDomain(newDomain);
        }
        return company;
    }

    public String getNextReferenceId() {
        Long nextId = CoreServiceLocator.getSurrogateKeyService().getKey("company.reference.id");
        return (nextId.toString());
    }

    public int findChildCompanyCount(Long parentId) throws DataException {
        log.debug("findChildCompanyCount() called");
        Session session = ThreadProperties.getSession();
        int count = 0;
        try {

            Iterator results = session.createQuery(
                    "select count(distinct company.id) from org.vectrics.company.Company company"
                            + "  where company.parent.id=? and company.voided='F'").setLong(0, parentId.longValue())
                    .iterate();

            while (results.hasNext()) {
                Object row = (Object) results.next();
                Long countInteger = (Long) row;
                count = countInteger.intValue();
            }
        } catch (Exception ex) {
            log.error("createCompany() - exception", ex);
            throw new DataException(ex);
        }
        return (count);
    }

    public List findChildCompanies(Long parentId, int startIndex, int endIndex) {
        log.debug("findChildCompanies() called");
        Session session = ThreadProperties.getSession();
        List list = null;
        try {
            Query query = session.createQuery("select company from org.vectrics.company.Company company "
                    + "where company.parent.id='" + parentId + "' and company.voided='F' order by company.name");
            query.setMaxResults(1 + endIndex - startIndex);
            query.setFirstResult(startIndex);
            list = query.list();
        } catch (Exception ex) {
            log.error("createCompany() - exception", ex);
            throw new DataException(ex);
        }
        return (list);

    }

    public Filter createFilterForCriteria(CompanySelectCriteria criteria, boolean getCount) {
        Filter filter = new Filter();

        if (getCount) {
            filter.addSelectField("count(distinct company)");
        } else {
            filter.addSelectField("distinct company");
            filter.addOrderBy("company.name");
        }
        filter.addFrom("org.vectrics.company.Company", "company");

        if (criteria.getVoidedType() == Criteria.VOID_NO) {
            filter.addCondition("company.voided='F'");
        }

        if (StringUtils.isNullOrBlank(criteria.getName()) == false) {
            Selector nameSelector = filter.getSelector().addChildSelector(Selector.CONJUNTION_OR);
            nameSelector.addCondition("company.name like '" + criteria.getName() + "%'");
            nameSelector.addParameterCondition("company.name", "=", criteria.getName());
        }

        if ((criteria.getDomains() != null) && (criteria.getDomains().size() > 0)) {
            Selector domainSelector = filter.getSelector().addChildSelector(Selector.CONJUNTION_OR);
            Iterator iter = criteria.getDomains().iterator();
            while (iter.hasNext()) {
                Domain domain = (Domain) iter.next();
                domainSelector.addParameterCondition("company.domain.id", "=", domain.getId());
            }
        }

        criteria.addConditionsToFilter(filter, "company");

        log.info("Company Select filter: " + filter.getStatement());
        return (filter);
    }

    public int findCompanyCount(CompanySelectCriteria criteria) throws DataException {
        log.debug("findCompanyCount(criteria) called");
        if (criteria == null) {
            throw new DataException("Criteria was passed to this method as null");
        }
        Session session = ThreadProperties.getSession();
        int count = 0;
        try {
            Filter filter = this.createFilterForCriteria(criteria, true);
            Query query = filter.createQuery(session);

            Iterator results = query.iterate();

            while (results.hasNext()) {
                Object row = (Object) results.next();
                Long countInteger = (Long) row;
                count = countInteger.intValue();
            }
        } catch (Exception ex) {
            log.error("createCompany() - exception", ex);
            throw new DataException(ex);
        }
        return (count);
    }

    public void updateCompanyPersonGroup(CompanyPersonGroup companyPersonGroup) {
        ThreadProperties.getSession().saveOrUpdate(companyPersonGroup);
    }

    public void removeCompanyPersonGroup(CompanyPersonGroup companyPersonGroup) {
        ThreadProperties.getSession().delete(companyPersonGroup);
    }

    public List findCompanyGroupTypes() {
        Filter filter = new Filter();
        filter.addFrom("CompanyPersonGroupType", "companyPersonGroup");
        filter.addSelectField("companyPersonGroup");
        filter.addCondition("companyPersonGroup.voided='F'");

        List list = null;
        Query query = filter.createQuery(ThreadProperties.getSession());
        list = query.list();
        return (list);
    }
	public List findCompanyGroups(String code) {
		org.hibernate.Criteria criteria = ThreadProperties.getSession().createCriteria(CompanyPersonGroup.class);
		
		criteria.createCriteria("companyPersonGroupType").add(Restrictions.eq("code", code));
		
		return criteria.list();
	}
	
	public void updateRecruiters(List<Employee> recruiters){
		ArrayList<CompanyPersonGroup> oldRecruiters = (ArrayList<CompanyPersonGroup>) findCompanyGroups(RecruitCompanyService.GROUP_RECRUITER);
		
		for (Iterator<CompanyPersonGroup> iterator = oldRecruiters.iterator(); iterator.hasNext();) {
			CompanyPersonGroup recruiter = iterator.next();
			this.removeCompanyPersonGroup(recruiter);
		}
		ThreadProperties.getSession().flush();
		CompanyPersonGroupType companyPersonGroupType = CoreServiceLocator.getCompanyService().findCompanyGroupType(RecruitCompanyService.GROUP_RECRUITER);
		
		for (Iterator<Employee> iterator = recruiters.iterator(); iterator.hasNext();) {
			Employee employee = iterator.next();
			
			CompanyPersonRole companyPersonRole = findCompanyPerson(employee.getCompany(), employee.getPerson()).getCurrentRole();
			
			CompanyPersonGroup newRecruiter = new CompanyPersonGroup();
			newRecruiter.setCompanyPersonGroupType(companyPersonGroupType);
			newRecruiter.setCompanyPersonRole(companyPersonRole);
			
			updateCompanyPersonGroup(newRecruiter);
		}
		
	}
	

	public List findCompanies(CompanySelectCriteria criteria, int startIndex, int endIndex) {
        log.debug("findCompanies(criteria, startIndex, endIndex) called");
        Filter filter = this.createFilterForCriteria(criteria, false);
        Session session = ThreadProperties.getSession();
        List list = null;
        Query query = filter.createQuery(session);
        query.setMaxResults(1 + endIndex - startIndex);
        query.setFirstResult(startIndex);
        list = query.list();
        return (list);
    }

    public void updateCompanyPerson(CompanyPerson companyPerson) {
        // if (companyPerson.getRoles().size() == 0)
        // throw new SystemException("No roles assigned to company person");
        boolean newEmployee = false;
        if (companyPerson.getId() == null) {
            newEmployee = true;
        }
        if (companyPerson.getCompany().getId() == null)
            throw new SystemException("CompanyPerson has company assigned that has null id");
        if (companyPerson.getPerson().getId() == null)
            throw new SystemException("CompanyPerson has person assigned that has null id");
        Session session = ThreadProperties.getSession();
        session.saveOrUpdate(companyPerson);

        Iterator iter = companyPerson.getRoles().iterator();
        while (iter.hasNext()) {
            CompanyPersonRole role = (CompanyPersonRole) iter.next();
            session.saveOrUpdate(role);
        }
        if (newEmployee) {
            Event createEvent = new Event();
            createEvent.setDomain(companyPerson.getCompany().getDomain());
            createEvent.setDescription("Employee created");
            EventType createEventType = CoreServiceLocator.getEventService().findEventType(Employee.EVENT_CREATED);
            createEvent.setEventType(createEventType);
            String eventDescription = createEvent.getDescription() + " (id = " + companyPerson.getId() + ")";
            createEvent.setDescription(eventDescription);
            createEvent.addAttachment(companyPerson, Employee.OBJECT_TYPE, "User that was created. ID = "
                    + companyPerson.getId());
            CoreServiceLocator.getEventService().updateEvent(createEvent);
        }
    }

    public CompanyPerson findCompanyPerson(Company company, Person person) {
        log.debug("findCompanyPerson()");
        CompanyPerson companyPerson = null;
        Filter filter = new Filter();
        filter.addSelectField("companyPerson");
        filter.addFrom("org.vectrics.company.CompanyPerson", "companyPerson");
        filter.addParameterCondition("companyPerson.company.id", "=", company.getId());
        filter.addParameterCondition("companyPerson.person.id", "=", person.getId());

        Session session = ThreadProperties.getSession();
        List list = null;
        Query query = filter.createQuery(session);
        list = query.list();
        if ((list != null) && (list.size() > 0)) {
            companyPerson = (CompanyPerson) list.iterator().next();
        }

        if (CoreServiceLocator.getConfiguration().getTestMode()) {
            if (companyPerson != null) {
                if (companyPerson.getLastRole() == null)
                    throw new SystemException("TestMode Assertion - CompanyPerson does not have any roles");
            }
        }
        return (companyPerson);
    }

    public void removeCompanyPerson(CompanyPerson companyPerson) {
        Session session = ThreadProperties.getSession();
        try {
            session.delete(companyPerson);
        } catch (Exception ex) {
            log.error("removeCompanyPerson() - exception", ex);
            throw new DataException(ex);
        }
    }

    public int findCompanyPersonCount(CompanyPersonCriteria criteria) {
        Session session = ThreadProperties.getSession();
        int count = 0;
        try {
            Filter filter = this.createCompanyPersonFilter(criteria, false);
            filter.addSelectField("count(distinct companyPerson.id)");

            Query query = filter.createQuery(session);

            Iterator results = query.iterate();

            while (results.hasNext()) {
                Object row = (Object) results.next();
                Long countInteger = (Long) row;
                count = countInteger.intValue();
            }
        } catch (Exception ex) {
            log.error("createCompany() - exception", ex);
            throw new DataException(ex);
        }
        return (count);
    }

    public Filter createCompanyPersonFilter(CompanyPersonCriteria criteria, boolean ordered) {
        Filter filter = new Filter();
        filter.addFrom("Employee", "companyPerson");

        if (criteria.getCompany() != null) {
            filter.addParameterCondition("companyPerson.company.id", "=", criteria.getCompany().getId());
        }

        if (criteria.getPerson() != null) {
            filter.addParameterCondition("companyPerson.person.id", "=", criteria.getPerson().getId());
        }

        if ((criteria.getDomains() != null) && (criteria.getDomains().size() > 0)) {
            Selector domainSelector = filter.getSelector().addChildSelector(Selector.CONJUNTION_OR);
            Iterator iter = criteria.getDomains().iterator();
            while (iter.hasNext()) {
                Domain domain = (Domain) iter.next();
                domainSelector.addParameterCondition("companyPerson.company.domain.id", "=", domain.getId());
            }
        }

        filter.addCondition("companyPerson.voided='F'");
        if (ordered) {
            if (criteria.getPerson() == null) {
                filter.addOrderBy("companyPerson.person.lastName, companyPerson.person.firstName");
            } else {
                filter.addOrderBy("companyPerson.company.name");
            }
        }
        return (filter);
    }

    public List findCompanyPersons(CompanyPersonCriteria criteria, int startIndex, int endIndex) {
        log.debug("findCompanyPersons()");
        Session session = ThreadProperties.getSession();
        List list = null;
        try {
            Filter filter = this.createCompanyPersonFilter(criteria, true);
            filter.addSelectField("companyPerson");
            Query query = filter.createQuery(session);
            query.setMaxResults(1 + endIndex - startIndex);
            query.setFirstResult(startIndex);
            list = query.list();
        } catch (Exception ex) {
            log.error("createCompany() - exception", ex);
            throw new DataException(ex);
        }
        return (list);
    }

    public CompanyPersonRoleType findCompanyPersonRoleType(String code) {
        CompanyPersonRoleType roleType = null;

        Session session = ThreadProperties.getSession();
        try {
            roleType = (CompanyPersonRoleType) session.load(CompanyPersonRoleType.class, code);
        } catch (Exception ex) {
            log.debug("findCompanyPersonRoleType() - exception" + ex.getMessage());
            throw new DataException("findCompanyPersonRoleType() - exception", ex);
        }
        if (roleType == null)
            throw new SystemException("Could not find role type for code: " + code);
        return (roleType);
    }

    public CompanyPerson findCompanyPerson(Long companyPersonId) {
        CompanyPerson companyPerson = null;
        if (companyPersonId == null) {
            log.debug("findCompanyPerson() - null id, returning null object");
        } else {
            log.debug("findCompanyPerson() - finding comapny with id");
            Session session = ThreadProperties.getSession();
            companyPerson = (CompanyPerson) session.load(CompanyPerson.class, companyPersonId);
        }
        return (companyPerson);
    }

    public Company findCompany(Long id) throws DataException {
        Company company = null;
        if (id == null) {
            log.debug("findCompany() - null id, returning null object");
        } else {
            log.debug("findCompany() - finding comapny with id");
            Session session = ThreadProperties.getSession();
            try {
                company = (Company) session.load(Company.class, id);
            } catch (Exception ex) {
                log.debug("findCompany() - exception" + ex.getMessage());
                throw new DataException("findCompany() - exception", ex);
            }
        }
        return (company);

    }

    public void removeCompany(Company company) throws DataException {
        company.setVoided(true);

        if (company != null) {
            log.debug("removeCompany() - finding comapny with id");
            Session session = ThreadProperties.getSession();
            session.update(company);
        }
    }

    /**
	 * 
	 */
    public Company updateCompany(Company updateCompany) throws DataException {
        log.debug("updateCompany()");

        if (updateCompany.getDomain() == null)
            updateCompany.setDomain(ThreadProperties.getDomain());

        if ((updateCompany.getReferenceId() == null) || (updateCompany.getReferenceId().trim().length() == 0)) {
            updateCompany.setReferenceId(this.getNextReferenceId());
        }

        Session session = null;
        session = ThreadProperties.getSession();
        session.saveOrUpdate(updateCompany);

        return (updateCompany);
    }

    public Company findCompanyWithReferenceId(String id) throws DataException {
        log.debug("findUserContactInfo()");
        Company company = null;
        Session session = ThreadProperties.getSession();
        log.debug("getContactInfo() - querying hibernate...");
        Iterator iter = session.createQuery(
                "from Company as company where (company.referenceId = ?) and (company.voided='F')").setString(0, id)
                .iterate();
        if (iter.hasNext()) {
            company = (Company) iter.next();
        }
        log.debug("getContactInfo() - querying hibernate, done");

        return (company);
    }

    public List findCompanyUsers(Company company) {
        log.debug("updateCompany()");
        List companyUsers = null;
        Session session = ThreadProperties.getSession();
        companyUsers = session.createQuery("from CompanyUser as companyUser where companyUser.company.id = ?").setLong(
                0, company.getId().longValue()).list();
        return (companyUsers);
    }

    public List findCompanyUsersForUser(Long userId) throws DataException {
        log.debug("updateCompany()");
        List companyUsers = null;
        Session session = ThreadProperties.getSession();
        companyUsers = session.createQuery("from CompanyUser as companyUser where companyUser.userId = ?").setLong(0,
                userId.longValue()).list();
        return (companyUsers);
    }

    public CompanyPerson findCompanyPerson(Long companyId, Long personId) {
        Session session = ThreadProperties.getSession();
        CompanyPerson companyUser = null;
        Iterator iter = session.createQuery("from CompanyUser as companyUser where companyUser.companyId = ?").setLong(
                0, companyId.longValue()).setLong(1, personId.longValue()).iterate();
        if (iter.hasNext()) {
            companyUser = (CompanyPerson) iter.next();
        }
        return (companyUser);
    }

    public void removeCompanyUser(Long companyId, Long personId) throws DataException {
        CompanyPerson companyUser = findCompanyPerson(companyId, personId);
        if (companyUser != null) {
            Session session = ThreadProperties.getSession();
            try {
                session.delete(companyUser);
            } catch (Exception ex) {
                log.error("removeCompanyUser() - exception", ex);
                throw new DataException(ex);
            }
        }
    }

    public void saveCompanyUser(CompanyPerson companyUser) throws DataException {
        Session session = ThreadProperties.getSession();
        try {
            session.saveOrUpdate(companyUser);
        } catch (Exception ex) {
            log.error("saveCompanyUser() - exception", ex);
            throw new DataException(ex);
        }
    }

    public Set findCompaniesForDomains(Set domains) {
        Set companies = new HashSet();
        if (domains.size() > 0) {
            Session session = ThreadProperties.getSession();
            String queryString = "select company from org.vectrics.company.Company company ";
            queryString += "where (company.voided = false) ";

            Iterator iter = domains.iterator();

            if (iter.hasNext()) {
                queryString += " AND (";
            }

            while (iter.hasNext()) {
                Domain domain = (Domain) iter.next();
                if (iter.hasNext()) {
                    queryString += " company.domain.id = " + domain.getId().toString() + " or ";
                } else {
                    queryString += " company.domain.id = " + domain.getId().toString() + "  )";
                }
            }

            Query query = session.createQuery(queryString);
            companies.addAll(query.list());
        }
        return (companies);
    }

    public CompanyPersonRole findCompanyPersonRole(Long id) {
        return (CompanyPersonRole) ThreadProperties.getSession().load(CompanyPersonRole.class, id);
    }

    public void updateCompanyPersonRole(CompanyPersonRole role) {
        ThreadProperties.getSession().saveOrUpdate(role);
    }

    public CompanyPersonGroupType findCompanyGroupType(String code) {
        CompanyPersonGroupType groupType = (CompanyPersonGroupType) ThreadProperties.getSession().load(
                CompanyPersonGroupType.class, code);
        return (groupType);
    }

    /**
     * @see org.vectrics.company.CompanyService#findAllEmployees()
     */
    public List<Employee> findAllEmployees() {
        Session session = ThreadProperties.getSession();
        return session.createQuery("from Employee").list();
    }

    /**
     * @see org.vectrics.company.CompanyService#findEmployeeForIdPerson(Long)
     */
    public CompanyPerson findEmployeeForIdPerson(Long idPerson) {
        Session session = ThreadProperties.getSession();
        Query query = session.createQuery("from CompanyPerson as employee " + "where employee.person.id = :id");
        query.setLong("id", idPerson);
        CompanyPerson resultado = null;
        List empleados = query.list();
        // Si no es nulo tomo el primero
        if (!empleados.isEmpty()) {
            resultado = (CompanyPerson) query.list().get(0);
        }
        return resultado;
    }

    /**
     * @see org.vectrics.company.CompanyService#findAllCompany()
     */
    public List<Company> findAllCompany() {
        Session session = ThreadProperties.getSession();
        Query query = session.createQuery("from Company as company where company.voided = false");
        List<Company> companias = query.list();
        return companias;
    }

    /**
     * @see org.vectrics.company.CompanyService#findEmployee(Long, Long)
     */
    public Employee findEmployee(Long idPerson, Long idCompany) {
        Session session = ThreadProperties.getSession();
        Query query = session.createQuery("from Employee as employee " + "where employee.person.id = :id "
                + "  and employee.company.id = :idCompany");
        // TODO: se debe agregar fecha de status de fin como condicion
        query.setLong("id", idPerson);
        query.setLong("idCompany", idCompany);
        Employee resultado = null;
        List empleados = query.list();
        if (!empleados.isEmpty()) {
            resultado = (Employee) query.list().get(0);
        }
        return resultado;
    }

    /**
     * @see org.vectrics.company.CompanyService#findEmployee(Long)
     */
    public Employee findEmployee(Long id) {
        Session session = ThreadProperties.getSession();
        return (Employee) session.get(Employee.class, id);
    }

    /**
     * @see org.vectrics.company.CompanyService#findStatusForPersonId(Long,
     *      Long)
     */
    public List<JobTerm> findStatusForPersonId(Long idPerson, Long idCompany) {
        // Busco el emploado
        Employee employee = this.findEmployee(idPerson, idCompany);
        Session session = ThreadProperties.getSession();
        List<JobTerm> terms = new ArrayList<JobTerm>();
        // si tiene un estado.
        if (employee.getCurrentStatus() != null) {
            // Cargo el estado actual
            terms.add(employee.getCurrentStatus().getStatusType());
            // Genero el query donde busco las referencias del estado en que
            // esta el empleado.
            Query query = session.createQuery(" from JobTermReference as reference "
                    + " where reference.fromTerm.id = :idTerm ");
            query.setLong("idTerm", employee.getCurrentStatus().getStatusType().getId());
            List<JobTermReference> references = query.list();
            // recorro todas las referencias para devolver los posibles estados
            // para el empleado.
            for (JobTermReference reference : references) {
                terms.add(reference.getToTerm());
            }
        } else {
            terms.addAll(RecruitServiceLocator.getJobProvider().findAllJobTerm());
        }
        return terms;
    }

    /**
     * @see org.vectrics.company.CompanyService#findJobTermReference(JobTerm,
     *      JobTerm)
     */
    public JobTermReference findJobTermReference(JobTerm toJobTerm, JobTerm fromJobTerm) {
        Session session = ThreadProperties.getSession();
        // Genero el query donde busco las referencias del estado en que esta el
        // empleado.
        Query query = session.createQuery(" from JobTermReference as reference "
                + " where reference.toTerm.id = :idToTerm " + "   and reference.fromTerm.id = :idFromTerm ");
        query.setLong("idToTerm", toJobTerm.getId());
        query.setLong("idFromTerm", fromJobTerm.getId());
        List<JobTermReference> references = query.list();
        JobTermReference resultado = null;
        if (!references.isEmpty()) {
            resultado = references.get(0);
        }
        return resultado;
    }

}
